package net.easyjava.third.db.utils;

import net.easyjava.third.db.annotation.Column;
import net.easyjava.third.db.annotation.Table;
import net.easyjava.tools.object.ObjectTools;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by wxnacy on 16/6/29.
 */
public class DBQuery {
    private Class clazz;
    private ResultSet rs;

    public DBQuery() {
    }

    public DBQuery(Class clazz, ResultSet rs) {
        this.clazz = clazz;
        this.rs = rs;
    }

    /**
     * 将查询结果反射为列表
     * @param <T>
     * @return
     * @throws SQLException
     * @throws IllegalAccessException
     * @throws InstantiationException
     * @throws InvocationTargetException
     */
    public final <T> List<T> parseArray() throws SQLException, IllegalAccessException, InstantiationException, InvocationTargetException, NoSuchMethodException {
        List<T> list = new ArrayList<>();
        while(rs.next()){
            T t = parseObject();
            list.add(t);
        }
        return list;
    }

    /**
     * 将查询结果反射为object
     * @param <T>
     * @return
     * @throws SQLException
     * @throws IllegalAccessException
     * @throws InvocationTargetException
     * @throws InstantiationException
     */
    public final  <T> T parseObject() throws SQLException, IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchMethodException {
        Object obj = this.clazz.newInstance();
        ResultSetMetaData rsmd = rs.getMetaData();
        int size = rsmd.getColumnCount();

        for(int i=1;i<=size;i++) {
            String name = rsmd.getColumnName(i);
            Object value = rs.getObject(name);
            obj = getColumn(obj,name,value);
        }
        T t = (T) obj;
        return t;
    }


    /**
     * 找寻对应的field赋值
     * @param obj
     * @param columnName
     * @param value
     * @return
     * @throws IllegalAccessException
     * @throws InstantiationException
     * @throws InvocationTargetException
     */
    public static Object getColumn(Object obj,String columnName,Object value) throws IllegalAccessException, InstantiationException, InvocationTargetException, NoSuchMethodException {
        Class clazz = obj.getClass();
        Field[] fields = clazz.getDeclaredFields();
        ObjectTools objectTools = new ObjectTools(obj);
        for(Field field:fields){
            String fieldName = field.getName();
            String colName;
            boolean isCol = field.isAnnotationPresent(Column.class);
            if(isCol){
                Column column = field.getAnnotation(Column.class);
                colName = column.value();
            }else{
                colName = field.getName();
            }
            if(columnName.equalsIgnoreCase(colName)){

//                ObjectTools.invokeSetMethod(obj,field,value);
                objectTools.invokeSetMethod(field, value);
//                setData(obj, fieldName, value);
            }

        }
        return obj;
    }


}
